package cn.iocoder.yudao.module.system.service.workorder;

import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.module.system.controller.admin.statistics.vo.OverallRespVO;
import cn.iocoder.yudao.module.system.controller.admin.workappendage.vo.WorkAppendageSaveReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
import cn.iocoder.yudao.module.system.dal.dataobject.workappendage.WorkAppendageDO;
import cn.iocoder.yudao.module.system.dal.dataobject.workhanging.WorkHangingDO;
import cn.iocoder.yudao.module.system.dal.dataobject.workrack.WorkRackDO;
import cn.iocoder.yudao.module.system.dal.dataobject.worksaleinventory.WorkSaleInventoryDO;
import cn.iocoder.yudao.module.system.dal.dataobject.worksaleoutbound.WorkSaleOutboundDO;
import cn.iocoder.yudao.module.system.dal.dataobject.workstore.WorkStoreDO;
import cn.iocoder.yudao.module.system.dal.mysql.user.AdminUserMapper;
import cn.iocoder.yudao.module.system.dal.mysql.workappendage.WorkAppendageMapper;
import cn.iocoder.yudao.module.system.dal.mysql.workhanging.WorkHangingMapper;
import cn.iocoder.yudao.module.system.dal.mysql.workrack.WorkRackMapper;
import cn.iocoder.yudao.module.system.dal.mysql.worksaleinventory.WorkSaleInventoryMapper;
import cn.iocoder.yudao.module.system.dal.mysql.worksaleoutbound.WorkSaleOutboundMapper;
import cn.iocoder.yudao.module.system.dal.mysql.workstore.WorkStoreMapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import org.apache.commons.math3.stat.descriptive.summary.Sum;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.*;
import cn.iocoder.yudao.module.system.controller.admin.workorder.vo.*;
import cn.iocoder.yudao.module.system.dal.dataobject.workorder.WorkOrderDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;

import cn.iocoder.yudao.module.system.dal.mysql.workorder.WorkOrderMapper;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.diffList;
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;

/**
 * 工单管理 Service 实现类
 *
 * @author 芋道源码
 */
@Service
@Validated
public class WorkOrderServiceImpl implements WorkOrderService {

    @Resource
    private WorkOrderMapper workOrderMapper;
    @Resource
    private AdminUserMapper adminUserMapper;
    @Resource
    private WorkAppendageMapper appendageMapper;
    @Resource
    private WorkHangingMapper workHangingMapper;
    @Resource
    private WorkRackMapper workRackMapper;
    @Resource
    private WorkStoreMapper workStoreMapper;
    @Resource
    private WorkSaleInventoryMapper workSaleInventoryMapper;
    @Resource
    private WorkSaleOutboundMapper workSaleOutboundMapper;

    @Override
    public Long createWorkOrder(WorkOrderSaveReqVO createReqVO) {
        QueryWrapper<WorkOrderDO> workOrderDOQueryWrapper = new QueryWrapper<>();
        workOrderDOQueryWrapper.eq("specification",createReqVO.getSpecification());
        List<WorkOrderDO> workOrderDOs = workOrderMapper.selectList(workOrderDOQueryWrapper);
        if(workOrderDOs!=null&&workOrderDOs.size()>0){
            throw exception(WORK_ORDER_NOT_EXISTS2);
        }
        // 插入
        WorkOrderDO workOrder = BeanUtils.toBean(createReqVO, WorkOrderDO.class);
        workOrderMapper.insert(workOrder);
        for (WorkAppendageSaveReqVO item:createReqVO.getAppendageSaveReqVOS()) {
            WorkAppendageDO appendageDO = BeanUtils.toBean(item, WorkAppendageDO.class);
            appendageDO.setWorkId(Math.toIntExact(workOrder.getId()));
            appendageMapper.insert(appendageDO);
        }
        // 返回
        return workOrder.getId();
    }

    @Override
    public void updateWorkOrder(WorkOrderSaveReqVO updateReqVO) {
        // 校验存在
        validateWorkOrderExists(updateReqVO.getId());
        // 更新
        WorkOrderDO updateObj = BeanUtils.toBean(updateReqVO, WorkOrderDO.class);
        workOrderMapper.updateById(updateObj);
        for (WorkAppendageSaveReqVO item:updateReqVO.getAppendageSaveReqVOS()) {
            WorkAppendageDO appendageDO = BeanUtils.toBean(item, WorkAppendageDO.class);
            appendageDO.setWorkId(Math.toIntExact(updateReqVO.getId()));
            appendageMapper.insert(appendageDO);
        }
    }

    @Override
    public void deleteWorkOrder(Long id) {
        WorkOrderDO workOrderDO = workOrderMapper.selectById(id);
        if(workOrderDO.getInventoryQuantity().compareTo(BigDecimal.valueOf(0L)) > 0){
            throw exception(WORK_ORDER_NOT_DELETE);
        }
        // 校验存在
        validateWorkOrderExists(id);
        // 删除
        workOrderMapper.deleteById(id);
    }

    @Override
    public void deleteWorkOrderListByIds(List<Long> ids) {
    // 校验存在
    validateWorkOrderExists(ids);
    // 删除
    workOrderMapper.deleteByIds(ids);
    }

    private void validateWorkOrderExists(List<Long> ids) {
        List<WorkOrderDO> list = workOrderMapper.selectByIds(ids);
        if (CollUtil.isEmpty(list) || list.size() != ids.size()) {
            throw exception(WORK_ORDER_NOT_EXISTS);
        }
    }

    private void validateWorkOrderExists(Long id) {
        if (workOrderMapper.selectById(id) == null) {
            throw exception(WORK_ORDER_NOT_EXISTS);
        }
    }

    @Override
    public WorkOrderRespVO getWorkOrder(Long id) {
        WorkOrderDO list = workOrderMapper.selectById(id);
        WorkOrderRespVO data = BeanUtils.toBean(list, WorkOrderRespVO.class);
        QueryWrapper<WorkAppendageDO> appendageDOQueryWrapper = new QueryWrapper<>();
        appendageDOQueryWrapper.eq("work_id",list.getId());
        List<WorkAppendageDO> workAppendageDOS = appendageMapper.selectList(appendageDOQueryWrapper);
        List<WorkAppendageSaveReqVO> appendageSaveReqVOS = BeanUtils.toBean(workAppendageDOS, WorkAppendageSaveReqVO.class);
        data.setAppendageSaveReqVOS(appendageSaveReqVOS);
        return data;
    }

    @Override
    public PageResult<WorkOrderRespVO> getWorkOrderPage(WorkOrderPageReqVO pageReqVO) {
        PageResult<WorkOrderDO> arr = workOrderMapper.selectPage(pageReqVO);
        PageResult<WorkOrderRespVO> data = BeanUtils.toBean(arr, WorkOrderRespVO.class);
        List<Integer> ids = new ArrayList<>();
        List<Integer> updateIds = new ArrayList<>();
        for (WorkOrderRespVO item:data.getList()) {
            ids.add(Math.toIntExact(item.getId()));
            updateIds.add(Integer.valueOf(item.getUpdater()));
            updateIds.add(item.getHangingUid());
            updateIds.add(item.getRackUid());
        }
        updateIds.add(0);
        ids.add(0);
        List<AdminUserDO> adminUserDOS = adminUserMapper.selectList(new QueryWrapper<AdminUserDO>().in("id",updateIds));
        QueryWrapper<WorkAppendageDO> appendageDOQueryWrapper = new QueryWrapper<>();
        appendageDOQueryWrapper.in("work_id",ids);
        List<WorkAppendageDO> workAppendageDOS = appendageMapper.selectList(appendageDOQueryWrapper);

        for (WorkOrderRespVO item:data.getList()) {
            item.setHangingQuantityDay(BigDecimal.valueOf(0));
            item.setRackingQuantityDay(BigDecimal.valueOf(0));
            item.setHangingQuantityMonth(BigDecimal.valueOf(0));
            item.setRackingQuantityMonth(BigDecimal.valueOf(0));
            item.setQuantityStock(item.getWhiteItemsNum().add(item.getBlackItemsNum()));
            Integer workdId = Math.toIntExact(item.getId());
            List<WorkAppendageSaveReqVO> appendageSaveReqVOS = new ArrayList<>();
            for (WorkAppendageDO item2:workAppendageDOS) {
                if(workdId.equals(item2.getWorkId())){
                    WorkAppendageSaveReqVO appendageSaveReqVO = BeanUtils.toBean(item2, WorkAppendageSaveReqVO.class);
                    appendageSaveReqVOS.add(appendageSaveReqVO);
                }
            }
            item.setAppendageSaveReqVOS(appendageSaveReqVOS);
            for (AdminUserDO userDO:adminUserDOS) {
                if(userDO.getId().equals(Long.valueOf(item.getUpdater()))){
                    item.setUpdaterName(userDO.getNickname());
                }
                if(item.getRackUid()!=null&&userDO.getId().equals(Long.valueOf(item.getRackUid()))){
                    item.setRackUidName(userDO.getNickname());
                }
                if(item.getHangingUid()!=null&&userDO.getId().equals(Long.valueOf(item.getHangingUid()))){
                    item.setHangingUidName(userDO.getNickname());
                }
            }
        }
        return data;
    }


    @Override
    public PageResult<OverallRespVO> overallStatistics(StatisticsPageReqVO pageReqVO) {
        PageResult<WorkOrderDO> arr = workOrderMapper.statisticsPage(pageReqVO);
        PageResult<OverallRespVO> data = BeanUtils.toBean(arr, OverallRespVO.class);
        List<Integer> ids = new ArrayList<>();
        for (OverallRespVO item:data.getList()) {
            ids.add(Math.toIntExact(item.getId()));
        }
        ids.add(0);

        QueryWrapper<WorkOrderDO> workOrderDOQueryWrapper = new QueryWrapper<>();
        if(pageReqVO.getCustomerName()!=null&&!pageReqVO.getCustomerName().equals("")){
            workOrderDOQueryWrapper.like("customer_name",pageReqVO.getCustomerName());
        }
        if(pageReqVO.getProductName()!=null&&!pageReqVO.getProductName().equals("")){
            workOrderDOQueryWrapper.like("product_name",pageReqVO.getProductName());
        }
        if(pageReqVO.getSpecification()!=null&&!pageReqVO.getSpecification().equals("")){
            workOrderDOQueryWrapper.like("specification",pageReqVO.getSpecification());
        }
        if(pageReqVO.getBillingMethod()!=null&&!pageReqVO.getBillingMethod().equals("")){
            workOrderDOQueryWrapper.like("billing_method",pageReqVO.getBillingMethod());
        }
        if(pageReqVO.getSubgroup()!=null&&!pageReqVO.getSubgroup().equals("")){
            workOrderDOQueryWrapper.like("subgroup",pageReqVO.getSubgroup());
        }
        List<WorkOrderDO> arrAll = workOrderMapper.selectList(workOrderDOQueryWrapper);

        List<Integer> ids2 = new ArrayList<>();
        for (WorkOrderDO item:arrAll) {
            ids2.add(Math.toIntExact(item.getId()));
        }
        ids2.add(0);
        QueryWrapper<WorkStoreDO> storeDOQueryWrapper = new QueryWrapper<>();
        storeDOQueryWrapper.in("work_id",ids);
        storeDOQueryWrapper.ge("create_time",pageReqVO.getCreateTimeStart());
        storeDOQueryWrapper.le("create_time",pageReqVO.getCreateTimeEnd());
        storeDOQueryWrapper.groupBy("work_id");
        storeDOQueryWrapper.select("work_id,sum(total_quantity) total_quantity");
        List<WorkStoreDO> workStoreDOS = workStoreMapper.selectList(storeDOQueryWrapper);
        QueryWrapper<WorkSaleInventoryDO> inventoryDOQueryWrapper = new QueryWrapper<>();
        inventoryDOQueryWrapper.ge("date",pageReqVO.getCreateTimeStart());
        inventoryDOQueryWrapper.le("date",pageReqVO.getCreateTimeEnd());
        inventoryDOQueryWrapper.groupBy("work_id");
        inventoryDOQueryWrapper.select("work_id,sum(quantity) quantity,sum(weight) weight");
        List<WorkSaleInventoryDO> saleInventoryDOS = workSaleInventoryMapper.selectList(inventoryDOQueryWrapper);
        QueryWrapper<WorkSaleOutboundDO> outboundDOQueryWrapper = new QueryWrapper<>();
        outboundDOQueryWrapper.in("work_id",ids);
        outboundDOQueryWrapper.ge("create_time",pageReqVO.getCreateTimeStart());
        outboundDOQueryWrapper.le("create_time",pageReqVO.getCreateTimeEnd());
        outboundDOQueryWrapper.groupBy("work_id");
        outboundDOQueryWrapper.select("work_id,sum(outbound_quantity) outbound_quantity,sum(outbound_weight) outbound_weight");
        List<WorkSaleOutboundDO> outboundDOS = workSaleOutboundMapper.selectList(outboundDOQueryWrapper);

        QueryWrapper<WorkStoreDO> storeDOQueryWrapper2 = new QueryWrapper<>();
        storeDOQueryWrapper2.in("work_id",ids2);
        storeDOQueryWrapper2.ge("create_time",pageReqVO.getCreateTimeStart());
        storeDOQueryWrapper2.le("create_time",pageReqVO.getCreateTimeEnd());
        storeDOQueryWrapper2.select("sum(total_quantity) total_quantity");
        WorkStoreDO workAppendageDO2 = workStoreMapper.selectOne(storeDOQueryWrapper2);
        QueryWrapper<WorkSaleInventoryDO> inventoryDOQueryWrapper2 = new QueryWrapper<>();
        inventoryDOQueryWrapper2.in("work_id",ids2);
        inventoryDOQueryWrapper2.ge("date",pageReqVO.getCreateTimeStart());
        inventoryDOQueryWrapper2.le("date",pageReqVO.getCreateTimeEnd());
        inventoryDOQueryWrapper2.select("sum(quantity) quantity,sum(weight) weight");
        WorkSaleInventoryDO saleInventoryDO2 = workSaleInventoryMapper.selectOne(inventoryDOQueryWrapper2);
        QueryWrapper<WorkSaleOutboundDO> outboundDOQueryWrapper2 = new QueryWrapper<>();
        outboundDOQueryWrapper2.in("work_id",ids2);
        outboundDOQueryWrapper2.ge("create_time",pageReqVO.getCreateTimeStart());
        outboundDOQueryWrapper2.le("create_time",pageReqVO.getCreateTimeEnd());
        outboundDOQueryWrapper2.select("sum(outbound_quantity) outbound_quantity,sum(outbound_weight) outbound_weight");
        WorkSaleOutboundDO outboundDO2 = workSaleOutboundMapper.selectOne(outboundDOQueryWrapper2);
        BigDecimal zoncz = new BigDecimal(0);
        for (WorkOrderDO item:arrAll) {
            Integer workdId = Math.toIntExact(item.getId());
            BigDecimal cz = BigDecimal.valueOf(0);
            BigDecimal price = new BigDecimal(0);
            if(item.getProductPrice()==null||item.getProductPrice().equals("")){
                price = item.getEstimatedUnitPrice()==null?new BigDecimal(0):item.getEstimatedUnitPrice();
            }else{
                String productPrice = item.getProductPrice().trim();
                price =new BigDecimal(productPrice);
            }
            for (WorkSaleInventoryDO item2:saleInventoryDOS) {
                if(workdId.equals(item2.getWorkId())){
                    if(item.getStorageMethod()!=null&&item.getStorageMethod().equals("2")){
                        item.setFinishedProductNum(item2.getWeight());
                        if(price.compareTo(new BigDecimal(0))>0){
//                            cz = item2.getWeight().multiply(price);
                            cz = item2.getWeight().divide(new BigDecimal(item.getProductSingleWeight()), 2, RoundingMode.HALF_UP).multiply(price);

                        }
                    }else{
                        item.setFinishedProductNum(new BigDecimal(item2.getQuantity()));
                        if(price.compareTo(new BigDecimal(0))>0){
                            cz = new BigDecimal(item2.getQuantity()).multiply(price);
                        }
                    }
                    zoncz = zoncz.add(cz);
                    break;
                }
            }
        }
        for (OverallRespVO item:data.getList()) {
            Integer workdId = Math.toIntExact(item.getId());
            item.setZonWhiteItemsNum(workAppendageDO2==null? BigDecimal.valueOf(0) :workAppendageDO2.getTotalQuantity());
            item.setZonSalesVolumes(new BigDecimal(outboundDO2==null? 0 :outboundDO2.getOutboundQuantity()));
            item.setZonFinishedProductNum(new BigDecimal(saleInventoryDO2==null? 0 :saleInventoryDO2.getQuantity()));
            item.setOutputValueZon(zoncz.toString());


            BigDecimal price = new BigDecimal(0);
            if(item.getProductPrice()==null||item.getProductPrice().equals("")){
                price = item.getEstimatedUnitPrice()==null?new BigDecimal(0):item.getEstimatedUnitPrice();
            }else{
                String productPrice = item.getProductPrice().trim();
                price =new BigDecimal(productPrice);
            }
            BigDecimal cz = BigDecimal.valueOf(0);

            for (WorkStoreDO item2:workStoreDOS) {
                if(workdId.equals(item2.getWorkId())){
                    item.setWhiteItemsNum(item2.getTotalQuantity());
                    break;
                }
            }
            for (WorkSaleInventoryDO item2:saleInventoryDOS) {
                if(workdId.equals(item2.getWorkId())){
                    if(item.getStorageMethod()!=null&&item.getStorageMethod().equals("2")){
                        item.setFinishedProductNum(item2.getWeight());
                        if(price.compareTo(new BigDecimal(0))>0){
//                            cz = item2.getWeight().multiply(price);
                            cz = item2.getWeight().divide(new BigDecimal(item.getProductSingleWeight()), 2, RoundingMode.HALF_UP).multiply(price);

                        }
                    }else{
                        item.setFinishedProductNum(new BigDecimal(item2.getQuantity()));
                        if(price.compareTo(new BigDecimal(0))>0){
                            cz = new BigDecimal(item2.getQuantity()).multiply(price);
                        }
                    }
                    item.setOutputValue(cz.toString());
                    break;
                }
            }
            for (WorkSaleOutboundDO item2:outboundDOS) {
                if(workdId.equals(item2.getWorkId())){
                    if(item.getStorageMethod()!=null&&item.getStorageMethod().equals("2")) {
                        item.setSalesVolumes(item2.getOutboundWeight());
                    }else{
                        item.setSalesVolumes(new BigDecimal(item2.getOutboundQuantity()));
                    }
                    break;
                }
            }
        }
        return data;
    }
    @Override
    public PageResult<DailyRespVO> dailyReport(StatisticsPageReqVO pageReqVO) {
        PageResult<WorkOrderDO> arr = workOrderMapper.statisticsPage(pageReqVO);
        QueryWrapper<WorkOrderDO> workOrderDOQueryWrapper = new QueryWrapper<>();
        if(pageReqVO.getCustomerName()!=null&&!pageReqVO.getCustomerName().equals("")){
            workOrderDOQueryWrapper.like("customer_name",pageReqVO.getCustomerName());
        }
        if(pageReqVO.getProductName()!=null&&!pageReqVO.getProductName().equals("")){
            workOrderDOQueryWrapper.like("product_name",pageReqVO.getProductName());
        }
        if(pageReqVO.getSpecification()!=null&&!pageReqVO.getSpecification().equals("")){
            workOrderDOQueryWrapper.like("specification",pageReqVO.getSpecification());
        }
        if(pageReqVO.getBillingMethod()!=null&&!pageReqVO.getBillingMethod().equals("")){
            workOrderDOQueryWrapper.like("billing_method",pageReqVO.getBillingMethod());
        }
        if(pageReqVO.getSubgroup()!=null&&!pageReqVO.getSubgroup().equals("")){
            workOrderDOQueryWrapper.like("subgroup",pageReqVO.getSubgroup());
        }
        List<WorkOrderDO> arrAll = workOrderMapper.selectList(workOrderDOQueryWrapper);
        PageResult<DailyRespVO> data = BeanUtils.toBean(arr, DailyRespVO.class);
        List<Integer> ids = new ArrayList<>();
        for (DailyRespVO item:data.getList()) {
            ids.add(Math.toIntExact(item.getId()));
        }
        ids.add(0);
        List<Integer> ids2 = new ArrayList<>();
        for (WorkOrderDO item:arrAll) {
            ids2.add(Math.toIntExact(item.getId()));
        }
        ids2.add(0);
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");

        // 转换为 LocalDate
        LocalDate startDate = LocalDate.parse(pageReqVO.getCreateTimeStart(), formatter);
        LocalDate endDate = LocalDate.parse(pageReqVO.getCreateTimeEnd(), formatter);

        // 生成每天的日期数组
        List<LocalDate> dateList = generateDateList(startDate, endDate);

        QueryWrapper<WorkHangingDO> hangingDOQueryWrapper = new QueryWrapper<>();
        hangingDOQueryWrapper.in("work_id",ids);
        hangingDOQueryWrapper.ge("hang_time",pageReqVO.getCreateTimeStart());
        hangingDOQueryWrapper.le("hang_time",pageReqVO.getCreateTimeEnd());
        hangingDOQueryWrapper.groupBy("work_id,hang_time2");
        hangingDOQueryWrapper.select("work_id,sum(total_quantity) total_quantity,DATE(hang_time) hang_time,DATE(hang_time) hang_time2");
        List<WorkHangingDO> workAppendageDOS = workHangingMapper.selectList(hangingDOQueryWrapper);

        QueryWrapper<WorkRackDO> rackDOQueryWrapper = new QueryWrapper<>();
        rackDOQueryWrapper.in("work_id",ids);
        rackDOQueryWrapper.ge("create_time",pageReqVO.getCreateTimeStart());
        rackDOQueryWrapper.le("create_time",pageReqVO.getCreateTimeEnd());
        rackDOQueryWrapper.groupBy("work_id,create_time2");
        rackDOQueryWrapper.select("work_id,sum(hang_num) hang_num,DATE(create_time) create_time2,DATE(create_time) create_time");
        List<WorkRackDO> rackDOS = workRackMapper.selectList(rackDOQueryWrapper);

        QueryWrapper<WorkHangingDO> hangingDOQueryWrapper2 = new QueryWrapper<>();
        hangingDOQueryWrapper2.in("work_id",ids2);
        hangingDOQueryWrapper2.ge("hang_time",pageReqVO.getCreateTimeStart());
        hangingDOQueryWrapper2.le("hang_time",pageReqVO.getCreateTimeEnd());
        hangingDOQueryWrapper2.select("sum(total_quantity) total_quantity");
        WorkHangingDO workAppendageDOS2 = workHangingMapper.selectOne(hangingDOQueryWrapper2);

        QueryWrapper<WorkRackDO> rackDOQueryWrapper2 = new QueryWrapper<>();
        hangingDOQueryWrapper2.in("work_id",ids2);
        rackDOQueryWrapper2.ge("create_time",pageReqVO.getCreateTimeStart());
        rackDOQueryWrapper2.le("create_time",pageReqVO.getCreateTimeEnd());
        rackDOQueryWrapper2.select("sum(hang_num) hang_num");
        WorkRackDO rackDOS2 = workRackMapper.selectOne(rackDOQueryWrapper2);

        for (DailyRespVO item:data.getList()) {
            item.setZonhangingQuantity(workAppendageDOS2==null? BigDecimal.valueOf(0) :workAppendageDOS2.getTotalQuantity());
            item.setZonrackingQuantity(rackDOS2==null? BigDecimal.valueOf(0) :rackDOS2.getHangNum());
            Integer workdId = Math.toIntExact(item.getId());
            List<StatisticsDateRespVO> statisticsDateRespVOS = new ArrayList<>();
            BigDecimal rackingQuantityDay = new BigDecimal(0);
            BigDecimal hangingQuantityDay = new BigDecimal(0);
            for (LocalDate date: dateList) {
                StatisticsDateRespVO statisticsDateRespVO = new StatisticsDateRespVO();
                statisticsDateRespVO.setDateDay(date.toString());
                statisticsDateRespVO.setHangingQuantityDay(BigDecimal.valueOf(0));
                statisticsDateRespVO.setRackingQuantityDay(BigDecimal.valueOf(0));
                for (WorkHangingDO item2:workAppendageDOS) {
                    if(workdId.equals(item2.getWorkId())&&item2.getHangTime().equals(date.atTime(0,0,0))){
                        statisticsDateRespVO.setHangingQuantityDay(item2.getTotalQuantity());
                        break;
                    }
                }
                for (WorkRackDO item3:rackDOS) {
                    if(workdId.equals(item3.getWorkId())&&item3.getCreateTime().equals(date.atTime(0,0,0))){
                        statisticsDateRespVO.setRackingQuantityDay(item3.getHangNum());
                        break;
                    }
                }
                rackingQuantityDay = rackingQuantityDay.add(statisticsDateRespVO.getRackingQuantityDay());
                hangingQuantityDay = hangingQuantityDay.add(statisticsDateRespVO.getHangingQuantityDay());
                statisticsDateRespVOS.add(statisticsDateRespVO);
            }
            item.setHangingQuantity(hangingQuantityDay);
            item.setRackingQuantity(rackingQuantityDay);
            if(item.getProductArea()!=null&&!item.getProductArea().equals("")){
                item.setProductZonArea(rackingQuantityDay.multiply(new BigDecimal(item.getProductArea())).toString());
            }
            item.setStatisticsDateRespVOS(statisticsDateRespVOS);
        }
        return data;
    }
    @Override
    public PageResult<WorkOrderRespVO> dailyProduction(StatisticsPageReqVO pageReqVO) {
        PageResult<WorkOrderDO> arr = workOrderMapper.statisticsPage(pageReqVO);
        PageResult<WorkOrderRespVO> data = BeanUtils.toBean(arr, WorkOrderRespVO.class);
        List<Integer> ids = new ArrayList<>();
        List<Integer> updateIds = new ArrayList<>();
        for (WorkOrderRespVO item:data.getList()) {
            ids.add(Math.toIntExact(item.getId()));
            updateIds.add(Integer.valueOf(item.getUpdater()));
            updateIds.add(item.getHangingUid());
            updateIds.add(item.getRackUid());
        }
        updateIds.add(0);
        ids.add(0);
        List<AdminUserDO> adminUserDOS = adminUserMapper.selectList(new QueryWrapper<AdminUserDO>().in("id",updateIds));
        QueryWrapper<WorkAppendageDO> appendageDOQueryWrapper = new QueryWrapper<>();
        appendageDOQueryWrapper.in("work_id",ids);
        List<WorkAppendageDO> workAppendageDOS = appendageMapper.selectList(appendageDOQueryWrapper);

        for (WorkOrderRespVO item:data.getList()) {
            item.setHangingQuantityDay(BigDecimal.valueOf(0));
            item.setRackingQuantityDay(BigDecimal.valueOf(0));
            item.setHangingQuantityMonth(BigDecimal.valueOf(0));
            item.setRackingQuantityMonth(BigDecimal.valueOf(0));
            item.setQuantityStock(item.getWhiteItemsNum().add(item.getBlackItemsNum()));
            Integer workdId = Math.toIntExact(item.getId());
            List<WorkAppendageSaveReqVO> appendageSaveReqVOS = new ArrayList<>();
            for (WorkAppendageDO item2:workAppendageDOS) {
                if(workdId.equals(item2.getWorkId())){
                    WorkAppendageSaveReqVO appendageSaveReqVO = BeanUtils.toBean(item2, WorkAppendageSaveReqVO.class);
                    appendageSaveReqVOS.add(appendageSaveReqVO);
                }
            }
            item.setAppendageSaveReqVOS(appendageSaveReqVOS);
            for (AdminUserDO userDO:adminUserDOS) {
                if(userDO.getId().equals(Long.valueOf(item.getUpdater()))){
                    item.setUpdaterName(userDO.getNickname());
                }
                if(item.getRackUid()!=null&&userDO.getId().equals(Long.valueOf(item.getRackUid()))){
                    item.setRackUidName(userDO.getNickname());
                }
                if(item.getHangingUid()!=null&&userDO.getId().equals(Long.valueOf(item.getHangingUid()))){
                    item.setHangingUidName(userDO.getNickname());
                }
            }
        }
        return data;
    }

    @Override
    public PageResult<WorkOrderRespVO> productionDetails(StatisticsPageReqVO pageReqVO) {
        PageResult<WorkOrderDO> arr = workOrderMapper.statisticsPage(pageReqVO);
        PageResult<WorkOrderRespVO> data = BeanUtils.toBean(arr, WorkOrderRespVO.class);
        List<Integer> ids = new ArrayList<>();
        List<Integer> updateIds = new ArrayList<>();
        for (WorkOrderRespVO item:data.getList()) {
            ids.add(Math.toIntExact(item.getId()));
            updateIds.add(Integer.valueOf(item.getUpdater()));
            updateIds.add(item.getHangingUid());
            updateIds.add(item.getRackUid());
        }
        updateIds.add(0);
        ids.add(0);
        List<AdminUserDO> adminUserDOS = adminUserMapper.selectList(new QueryWrapper<AdminUserDO>().in("id",updateIds));
        QueryWrapper<WorkAppendageDO> appendageDOQueryWrapper = new QueryWrapper<>();
        appendageDOQueryWrapper.in("work_id",ids);
        List<WorkAppendageDO> workAppendageDOS = appendageMapper.selectList(appendageDOQueryWrapper);

        for (WorkOrderRespVO item:data.getList()) {
            item.setHangingQuantityDay(BigDecimal.valueOf(0));
            item.setRackingQuantityDay(BigDecimal.valueOf(0));
            item.setHangingQuantityMonth(BigDecimal.valueOf(0));
            item.setRackingQuantityMonth(BigDecimal.valueOf(0));
            item.setQuantityStock(item.getWhiteItemsNum().add(item.getBlackItemsNum()));
            Integer workdId = Math.toIntExact(item.getId());
            List<WorkAppendageSaveReqVO> appendageSaveReqVOS = new ArrayList<>();
            for (WorkAppendageDO item2:workAppendageDOS) {
                if(workdId.equals(item2.getWorkId())){
                    WorkAppendageSaveReqVO appendageSaveReqVO = BeanUtils.toBean(item2, WorkAppendageSaveReqVO.class);
                    appendageSaveReqVOS.add(appendageSaveReqVO);
                }
            }
            item.setAppendageSaveReqVOS(appendageSaveReqVOS);
            for (AdminUserDO userDO:adminUserDOS) {
                if(userDO.getId().equals(Long.valueOf(item.getUpdater()))){
                    item.setUpdaterName(userDO.getNickname());
                }
                if(item.getRackUid()!=null&&userDO.getId().equals(Long.valueOf(item.getRackUid()))){
                    item.setRackUidName(userDO.getNickname());
                }
                if(item.getHangingUid()!=null&&userDO.getId().equals(Long.valueOf(item.getHangingUid()))){
                    item.setHangingUidName(userDO.getNickname());
                }
            }
        }
        return data;
    }

    @Override
    public PageResult<SummaryRespVO> summaryOutputAll(StatisticsPageReqVO pageReqVO) {
        PageResult<WorkOrderDO> arr = workOrderMapper.statisticsPage(pageReqVO);
        PageResult<SummaryRespVO> data = BeanUtils.toBean(arr, SummaryRespVO.class);
        List<String> ids = new ArrayList<>();
        for (SummaryRespVO item:data.getList()) {
            ids.add(item.getCustomerId());
        }
        ids.add("0");
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");

        // 转换为 LocalDate
        LocalDate startDate = LocalDate.parse(pageReqVO.getCreateTimeStart(), formatter);
        LocalDate endDate = LocalDate.parse(pageReqVO.getCreateTimeEnd(), formatter);

        // 生成每天的日期数组
        List<LocalDate> dateList = generateDateList(startDate, endDate);

        QueryWrapper<WorkSaleInventoryDO> inventoryDOQueryWrapper = new QueryWrapper<>();
        inventoryDOQueryWrapper.in("customer_id",ids);
        inventoryDOQueryWrapper.ge("date",pageReqVO.getCreateTimeStart());
        inventoryDOQueryWrapper.le("date",pageReqVO.getCreateTimeEnd());
        inventoryDOQueryWrapper.groupBy("customer_id,date");
        inventoryDOQueryWrapper.select("customer_id,DATE(date) date,sum(quantity) quantity,sum(weight) weight");
        List<WorkSaleInventoryDO> saleInventoryDOS = workSaleInventoryMapper.selectList(inventoryDOQueryWrapper);

        for (SummaryRespVO item:data.getList()) {
            BigDecimal price = new BigDecimal(0);
            if(item.getProductPrice()==null||item.getProductPrice().equals("")){
                price = item.getEstimatedUnitPrice()==null?new BigDecimal(0):item.getEstimatedUnitPrice();
            }else{
                String productPrice = item.getProductPrice().trim();
                price =new BigDecimal(productPrice);
            }
            BigDecimal czZon = BigDecimal.valueOf(0);
            List<StatisticsDateRespVO> statisticsDateRespVOS = new ArrayList<>();
            for (LocalDate date: dateList) {
                BigDecimal cz = BigDecimal.valueOf(0);
                StatisticsDateRespVO statisticsDateRespVO = new StatisticsDateRespVO();
                statisticsDateRespVO.setDateDay(date.toString());
                statisticsDateRespVO.setOutputValue(BigDecimal.valueOf(0));
                for (WorkSaleInventoryDO item2:saleInventoryDOS) {
                    if(item.getCustomerId().equals(item2.getCustomerId())&&item2.getDate().equals(date.atTime(0,0,0))){
                        if(item.getStorageMethod()!=null&&item.getStorageMethod().equals("2")){
                            if(price.compareTo(new BigDecimal(0))>0){
//                                cz = item2.getWeight().multiply(price);
                                cz = item2.getWeight().divide(new BigDecimal(item.getProductSingleWeight()), 2, RoundingMode.HALF_UP).multiply(price);

                            }
                        }else{
                            if(price.compareTo(new BigDecimal(0))>0){
                                cz = new BigDecimal(item2.getQuantity()).multiply(price);
                            }
                        }
                        czZon = czZon.add(cz);
                        item.setOutputValue(cz.toString());
                        break;
                    }
                }
                statisticsDateRespVOS.add(statisticsDateRespVO);
            }
            item.setOutputValue(czZon.toString());
            item.setStatisticsDateRespVOS(statisticsDateRespVOS);
        }
        return data;
    }
    @Override
    public PageResult<SummaryRespVO> summaryOutputDy(StatisticsPageReqVO pageReqVO) {
        PageResult<WorkOrderDO> arr = workOrderMapper.statisticsPage(pageReqVO);
        PageResult<SummaryRespVO> data = BeanUtils.toBean(arr, SummaryRespVO.class);
        List<Integer> ids = new ArrayList<>();
        for (SummaryRespVO item:data.getList()) {
            ids.add(Math.toIntExact(item.getId()));
        }
        ids.add(0);
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");

        // 转换为 LocalDate
        LocalDate startDate = LocalDate.parse(pageReqVO.getCreateTimeStart(), formatter);
        LocalDate endDate = LocalDate.parse(pageReqVO.getCreateTimeEnd(), formatter);

        // 生成每天的日期数组
        List<LocalDate> dateList = generateDateList(startDate, endDate);

        QueryWrapper<WorkSaleInventoryDO> inventoryDOQueryWrapper = new QueryWrapper<>();
        inventoryDOQueryWrapper.in("work_id",ids);
        inventoryDOQueryWrapper.ge("date",pageReqVO.getCreateTimeStart());
        inventoryDOQueryWrapper.le("date",pageReqVO.getCreateTimeEnd());
        inventoryDOQueryWrapper.groupBy("work_id,date");
        inventoryDOQueryWrapper.select("work_id,customer_id,DATE(date) date,sum(quantity) quantity,sum(weight) weight");
        List<WorkSaleInventoryDO> saleInventoryDOS = workSaleInventoryMapper.selectList(inventoryDOQueryWrapper);

        for (SummaryRespVO item:data.getList()) {
            Integer workdId = Math.toIntExact(item.getId());
            BigDecimal price = new BigDecimal(0);
            if(item.getProductPrice()==null||item.getProductPrice().equals("")){
                price = item.getEstimatedUnitPrice()==null?new BigDecimal(0):item.getEstimatedUnitPrice();
            }else{
                String productPrice = item.getProductPrice().trim();
                price =new BigDecimal(productPrice);
            }
            BigDecimal czZon = BigDecimal.valueOf(0);
            List<StatisticsDateRespVO> statisticsDateRespVOS = new ArrayList<>();
            for (LocalDate date: dateList) {
                BigDecimal cz = BigDecimal.valueOf(0);
                BigDecimal zonArea = BigDecimal.valueOf(0);
                StatisticsDateRespVO statisticsDateRespVO = new StatisticsDateRespVO();
                statisticsDateRespVO.setDateDay(date.toString());
                statisticsDateRespVO.setOutputValue(BigDecimal.valueOf(0));
                for (WorkSaleInventoryDO item2:saleInventoryDOS) {
                    if(workdId.equals(item2.getWorkId())&&item2.getDate().equals(date.atTime(0,0,0))){
                        if(item.getStorageMethod()!=null&&item.getStorageMethod().equals("2")){
                            if(price.compareTo(new BigDecimal(0))>0){
                                cz = item2.getWeight().divide(new BigDecimal(item.getProductSingleWeight()), 2, RoundingMode.HALF_UP).multiply(price);
                            }

                            if(item.getProductArea()!=null&&!item.getProductArea().equals("")){
                                item.setProductZonArea(item2.getWeight().divide(new BigDecimal(item.getProductSingleWeight()), 2, RoundingMode.HALF_UP).multiply(new BigDecimal(item.getProductArea())).toString());
                            }
                        }else{
                            if(price.compareTo(new BigDecimal(0))>0){
                                cz = new BigDecimal(item2.getQuantity()).multiply(price);
                            }
                            if(item.getProductArea()!=null&&!item.getProductArea().equals("")){
                                item.setProductZonArea(new BigDecimal(item2.getQuantity()).multiply(new BigDecimal(item.getProductArea())).toString());
                            }
                        }
                        czZon = czZon.add(cz);
                        item.setOutputValue(cz.toString());
                        break;
                    }
                }
                statisticsDateRespVOS.add(statisticsDateRespVO);
            }
            item.setOutputValue(czZon.toString());
            item.setStatisticsDateRespVOS(statisticsDateRespVOS);
        }
        return data;
    }

    @Override
    public void dayTask() {
        LocalDate today = LocalDate.now(); // 获取当前日期
        LocalDate firstDayOfMonth = today.with(TemporalAdjusters.firstDayOfMonth()); // 获取当月第一天
        if (today.equals(firstDayOfMonth)) {
            UpdateWrapper<WorkOrderDO> updateWrapper = new UpdateWrapper<>();
            updateWrapper.setSql("initial_quantity=white_items_num,inventory_quantity=0");
            workOrderMapper.update(updateWrapper);
        } else {
            System.out.println("今天不是这个月的第一天");
        }
    }

    // 生成从开始日期到结束日期的每一天
    private static List<LocalDate> generateDateList(LocalDate startDate, LocalDate endDate) {
        List<LocalDate> dates = new ArrayList<>();
        for (LocalDate date = startDate; !date.isAfter(endDate); date = date.plusDays(1)) {
            dates.add(date);
        }
        return dates;
    }

}
